#include <math.h>
#include <iostream>
using namespace std;
class Rational // 声明有理数类
{
public:
  Rational(int x = 0, int y = 1); // 构造函数
  void Print();
  Rational operator+(Rational a); // 重载运算符"+"
  Rational operator-(Rational a); // 重载运算符"-"
private:
  int num, den;
  void Optimi();
};                      // 优化有理数函数
// 声明构造函数
Rational::Rational(int x, int y) : num(x), den(y)
{
  Optimi();
}
void Rational::Optimi() // 定义有理数优化函数
{
  // 最大公约数
  int gcd;
  if (num == 0) // 若分子为0，则置分母为1后返回
  {
    den = 1;
    return;
  }
  gcd = (abs(num) > abs(den) ? abs(num) : abs(den));
  if (gcd == 0)
    return;                     // 若为0，则返回
  int i = gcd;
  for (; i > 1; i--) // 用循环找最大公约数
  {
    if ((num % i == 0) && (den % i == 0))
      break;
  }
  num /= i; // i为最大公约数,将分子、分母均整除它,重新赋值
  den /= i;
  // 若分子和分母均为负数，则结果为正，所以均改为正
  if (num < 0 && den < 0)
  {
    num = -num;
    den = -den;
  }
  else if (num < 0 || den < 0)
  { // 若分子和分母中只有一个为负数，则调整为分子取负，分母取正
    num = -abs(num);
    den = abs(den);
  }
}
void Rational::Print() // 输出有理数
{
  cout << num;
  // 当分子不为0且分母不为1时才显示"/分母“
  if (num != 0 && den != 1)
    cout << "/" << den << "\n";
  else
    cout << "\n";
}
Rational Rational::operator+(Rational a)
{ // “+”运算符重载函数，根据前面所列的算法写出表达式
  Rational r;
  r.den = a.den * den;
  r.num = a.num * den + a.den * num;
  r.Optimi();
  return r;
}
Rational Rational::operator-(Rational a)
{ // “-”运算符重载函数，根据前面所列的算法写出表达式
  Rational r;
  r.den = a.den * den;
  r.num = num * a.den - den * a.num;
  r.Optimi();
  return r;
}
int main()
{
  Rational r1(3, 14), r2(4, 14), r3, r4;
  r1.Print();
  r2.Print();
  r3 = r1 + r2; // 使用重载了的运算符“+”
  r3.Print();
  r4 = r1 - r2; // 使用重载了的运算符“-”
  r4.Print();
  return 0;
}
